using System;
using System.Data;
using System.Data.SqlClient;

namespace MessageBoard
{
	/// <summary>
	/// Summary description for Role.
	/// </summary>
	public class Role : Connection
	{
		#region Fields

		private int _Id;
		private User _User;
		private UserGroup _UserGroup;

		private Boolean _TheMessageBoard;
		private Group _Group;
		private Category _Category;
		private Forum _Forum;
		private Thread _Thread;
		private Post _Post;

		private Allow _CanViewGroups;
		private Allow _CanViewCategories;
		private Allow _CanViewForums;
		private Allow _CanViewThreads;
		private Allow _CanViewPosts;

		private Allow _CanAddGroups;

		private Allow _CanAddCategories;

		private Allow _CanAddForums;

		private Allow _CanAddThreads;

		private Allow _CanAddPosts;
		
		private Allow _CanEditGroups;
		private Allow _CanEditCategories;
		private Allow _CanEditForums;
		private Allow _CanEditThreads;
		private Allow _CanEditPosts;

		private Allow _CanEditHisThreads;
		private Allow _CanEditHisPosts;

		private Allow _CanDeleteGroups;
		private Allow _CanDeleteCategories;
		private Allow _CanDeleteForums;
		private Allow _CanDeleteThreads;
		private Allow _CanDeletePosts;

		private Allow _CanDeleteHisThreads;
		private Allow _CanDeleteHisPosts;

		private Allow _CanManageMessageBoardSecurity;
		private Allow _CanManageGroupsSecurity;
		private Allow _CanManageCategoriesSecurity;
		private Allow _CanManageForumsSecurity;
		private Allow _CanManageThreadsSecurity;
		private Allow _CanManagePostsSecurity;

		#endregion

		#region Constructor
		public Role()
		{
			Id = 0;
		}
		#endregion

		#region Get

		#region Get By DataRow & ID
		public static Role Get(System.Data.DataRow dr)
		{
			Role role = new Role();
			role.Id = int.Parse(dr["Id"].ToString());

			if(dr["UserId"].ToString()!="")
				role.User = User.Get(int.Parse(dr["UserId"].ToString()));
			else if(dr["UserGroupId"].ToString()!="")
				role.UserGroup = UserGroup.Get(int.Parse(dr["UserGroupId"].ToString()));

			role.TheMessageBoard = Convert.ToBoolean(dr["TheMessageBoard"].ToString());

			if(dr["GroupId"].ToString()!="")
				role.Group = Group.Get(int.Parse(dr["GroupId"].ToString()));
			else if(dr["CategoryId"].ToString()!="")
				role.Category = Category.Get(int.Parse(dr["CategoryId"].ToString()));
			else if(dr["ForumId"].ToString()!="")
				role.Forum = Forum.Get(int.Parse(dr["ForumId"].ToString()));
			else if(dr["ThreadId"].ToString()!="")
				role.Thread = Thread.Get(int.Parse(dr["ThreadId"].ToString()));
			else if(dr["PostId"].ToString()!="")
				role.Post = Post.Get(int.Parse(dr["PostId"].ToString()));

			role.CanViewGroups = (Allow)int.Parse(dr["CanViewGroups"].ToString());
			role.CanViewCategories = (Allow)int.Parse(dr["CanViewCategories"].ToString());
			role.CanViewForums = (Allow)int.Parse(dr["CanViewForums"].ToString());
			role.CanViewThreads = (Allow)int.Parse(dr["CanViewThreads"].ToString());
			role.CanViewPosts = (Allow)int.Parse(dr["CanViewPosts"].ToString());

			role.CanAddGroups = (Allow)int.Parse(dr["CanAddGroups"].ToString());

			role.CanAddCategories = (Allow)int.Parse(dr["CanAddCategories"].ToString());

			role.CanAddForums = (Allow)int.Parse(dr["CanAddForums"].ToString());

			role.CanAddThreads = (Allow)int.Parse(dr["CanAddThreads"].ToString());

			role.CanAddPosts = (Allow)int.Parse(dr["CanAddPosts"].ToString());
			
			role.CanEditGroups = (Allow)int.Parse(dr["CanEditGroups"].ToString());
			role.CanEditCategories = (Allow)int.Parse(dr["CanEditCategories"].ToString());
			role.CanEditForums = (Allow)int.Parse(dr["CanEditForums"].ToString());
			role.CanEditThreads = (Allow)int.Parse(dr["CanEditThreads"].ToString());
			role.CanEditPosts = (Allow)int.Parse(dr["CanEditPosts"].ToString());

			role.CanEditHisThreads = (Allow)int.Parse(dr["CanEditHisThreads"].ToString());
			role.CanEditHisPosts = (Allow)int.Parse(dr["CanEditHisPosts"].ToString());

			role.CanDeleteGroups = (Allow)int.Parse(dr["CanDeleteGroups"].ToString());
			role.CanDeleteCategories = (Allow)int.Parse(dr["CanDeleteCategories"].ToString());
			role.CanDeleteForums = (Allow)int.Parse(dr["CanDeleteForums"].ToString());
			role.CanDeleteThreads = (Allow)int.Parse(dr["CanDeleteThreads"].ToString());
			role.CanDeletePosts = (Allow)int.Parse(dr["CanDeletePosts"].ToString());

			role.CanDeleteHisThreads = (Allow)int.Parse(dr["CanDeleteHisThreads"].ToString());
			role.CanDeleteHisPosts = (Allow)int.Parse(dr["CanDeleteHisPosts"].ToString());

			role.CanManageMessageBoardSecurity = (Allow)int.Parse(dr["CanManageMessageBoardSecurity"].ToString());
			role.CanManageGroupsSecurity = (Allow)int.Parse(dr["CanManageGroupsSecurity"].ToString());
			role.CanManageCategoriesSecurity = (Allow)int.Parse(dr["CanManageCategoriesSecurity"].ToString());
			role.CanManageForumsSecurity = (Allow)int.Parse(dr["CanManageForumsSecurity"].ToString());
			role.CanManageThreadsSecurity = (Allow)int.Parse(dr["CanManageThreadsSecurity"].ToString());
			role.CanManagePostsSecurity = (Allow)int.Parse(dr["CanManagePostsSecurity"].ToString());

			return role;
		}


		public static Role Get(int id)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [Id] = @Id", DbConnection);
			getData.SelectCommand.Parameters.Add("@Id", id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}
		#endregion

		#region Get User Role
		public static Role Get(User user)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [TheMessageBoard] = 1", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(User user, Group group)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [GroupId] = @GroupId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.SelectCommand.Parameters.Add("@GroupId", group.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(User user, Category category)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [CategoryId] = @CategoryId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.SelectCommand.Parameters.Add("@CategoryId", category.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(User user, Forum forum)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [ForumId] = @ForumId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.SelectCommand.Parameters.Add("@ForumId", forum.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(User user, Thread thread)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [ThreadId] = @ThreadId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.SelectCommand.Parameters.Add("@ThreadId", thread.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(User user, Post post)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = @UserId AND [PostId] = @PostId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.SelectCommand.Parameters.Add("@PostId", post.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}
		#endregion

		#region Get UserGroup Role
		public static Role Get(UserGroup userGroup)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [TheMessageBoard] = 1", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(UserGroup userGroup, Group group)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [GroupId] = @GroupId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.SelectCommand.Parameters.Add("@GroupId", group.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(UserGroup userGroup, Category category)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [CategoryId] = @CategoryId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.SelectCommand.Parameters.Add("@CategoryId", category.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(UserGroup userGroup, Forum forum)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [ForumId] = @ForumId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.SelectCommand.Parameters.Add("@ForumId", forum.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(UserGroup userGroup, Thread thread)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [ThreadId] = @ThreadId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.SelectCommand.Parameters.Add("@ThreadId", thread.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}

		public static Role Get(UserGroup userGroup, Post post)
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = @UserGroupId AND [PostId] = @PostId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.SelectCommand.Parameters.Add("@PostId", post.Id);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return Get(ds.Tables[0].Rows[0]);
			}
			else
			{
				return null;
			}
		}
		#endregion

		#region Get All
		public static System.Collections.ArrayList GetAll(User user)
		{
			System.Collections.ArrayList arrayList = new System.Collections.ArrayList();
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM " + Connection.tblRole + " WHERE [UserId] = @UserId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserId", user.Id);
			getData.Fill(ds);
			foreach(System.Data.DataRow dr in ds.Tables[0].Rows)
			{
				arrayList.Add(Get(dr));
			}
			return arrayList;
		}

		public static System.Collections.ArrayList GetAll(UserGroup userGroup)
		{
			System.Collections.ArrayList arrayList = new System.Collections.ArrayList();
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter("SELECT * FROM " + Connection.tblRole + " WHERE [UserGroupId] = @UserGroupId", DbConnection);
			getData.SelectCommand.Parameters.Add("@UserGroupId", userGroup.Id);
			getData.Fill(ds);
			foreach(System.Data.DataRow dr in ds.Tables[0].Rows)
			{
				arrayList.Add(Get(dr));
			}
			return arrayList;
		}
		#endregion

		#endregion

		#region Check Permissions

		#region User
		/// <summary>
		/// Check if the user have the required permissions of the giving post or not.
		/// </summary>
		/// <param name="user">User</param>
		/// <param name="post">Post</param>
		/// <param name="permissions">The required permissions</param>
		/// <returns>Allow</returns>
		public static Allow Check(User user, Post post, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [PostId] = " + post.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{				
				// check the user group permissions
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, post, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, post, permissions)==Allow.No)
						return Allow.No;
				}
				// check the user permissions on the Thread level
				return Check(user, post.Thread, permissions);
			}
		}

		public static Allow Check(User user, Thread thread, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [ThreadId] = " + thread.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, thread, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, thread, permissions)==Allow.No)
						return Allow.No;
				}
				return Check(user, thread.Forum, permissions);
			}
		}

		public static Allow Check(User user, Forum forum, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [ForumId] = " + forum.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, forum, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, forum, permissions)==Allow.No)
						return Allow.No;
				}
				return Check(user, forum.Category, permissions);
			}
		}

		public static Allow Check(User user, Category category, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [CategoryId] = " + category.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, category, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, category, permissions)==Allow.No)
						return Allow.No;
				}
				return Check(user, category.Group, permissions);
			}
		}

		public static Allow Check(User user, Group group, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [GroupId] = " + group.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, group, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, group, permissions)==Allow.No)
						return Allow.No;
				}
				return Check(user, permissions);
			}
		}

		public static Allow Check(User user, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserId] = " + user.Id;
			query += " AND [TheMessageBoard] = 1";
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return  Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, permissions)==Allow.Yes)
						return Allow.Yes;
				}
				foreach(UsersInGroups usersInGroups in UsersInGroups.GetAll(user))
				{
					if (Check(usersInGroups.UserGroup, permissions)==Allow.No)
						return Allow.No;
				}
				return Allow.AsParent;
			}
		}
		#endregion

		#region UserGroup
		public static Allow Check(UserGroup userGroup, Post post, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [PostId] = " + post.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}

		public static Allow Check(UserGroup userGroup, Thread thread, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [ThreadId] = " + thread.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}

		public static Allow Check(UserGroup userGroup, Forum forum, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [ForumId] = " + forum.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}

		public static Allow Check(UserGroup userGroup, Category category, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [CategoryId] = " + category.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}

		public static Allow Check(UserGroup userGroup, Group group, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [GroupId] = " + group.Id;
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}

		public static Allow Check(UserGroup userGroup, params Role.Permission[] permissions)
		{
			string query = "SELECT * FROM [" + Connection.tblRole + "] WHERE [UserGroupId] = " + userGroup.Id;
			query += " AND [TheMessageBoard] = 1";
			if(CheckPermissions(query, Allow.No, permissions))
			{
				return Allow.No;
			}
			else if(CheckPermissions(query, Allow.Yes, permissions))
			{
				return Allow.Yes;
			}
			else
			{
				return Allow.AsParent;
			}
		}
		#endregion

		#region CheckPermission
		public static Boolean CheckPermissions(string query, Role.Allow allow, params Role.Permission[] permissions)
		{
			string str = "";
			if(allow == Allow.Yes)
				str= " = 1 ";
			else if(allow == Allow.No)
				str= " = 2 ";
			else
				str = " = 0";

			foreach(Role.Permission permission in permissions)
			{
				switch (permission)
				{
					case Role.Permission.CanViewGroups:
						query += " AND [CanViewGroups] " + str;
						break;
					case Role.Permission.CanAddCategories:
						query += " AND [CanAddCategories] " + str;
						break;
					case Role.Permission.CanEditCategories:
						query += " AND [CanEditCategories] " + str;
						break;
					case Role.Permission.CanDeleteCategories:
						query += " AND [CanDeleteCategories] " + str;
						break;
					case Role.Permission.CanAddForums:
						query += " AND [CanAddForums] " + str;
						break;
					case Role.Permission.CanEditForums:
						query += " AND [CanEditForums] " + str;
						break;
					case Role.Permission.CanDeleteForums:
						query += " AND [CanDeleteForums] " + str;
						break;
					case Role.Permission.CanViewCategories:
						query += " AND [CanViewCategories] " + str;
						break;
					case Role.Permission.CanViewForums:
						query += " AND [CanViewForums] " + str;
						break;
					case Role.Permission.CanViewThreads:
						query += " AND [CanViewThreads] " + str;
						break;
					case Role.Permission.CanViewPosts:
						query += " AND [CanViewPosts] " + str;
						break;
					case Role.Permission.CanAddGroups:
						query += " AND [CanAddGroups] " + str;
						break;
					case Role.Permission.CanAddThreads:
						query += " AND [CanAddThreads] " + str;
						break;
					case Role.Permission.CanAddPosts:
						query += " AND [CanAddPosts] " + str;
						break;
					case Role.Permission.CanEditGroups:
						query += " AND [CanEditGroups] " + str;
						break;
					case Role.Permission.CanEditThreads:
						query += " AND [CanEditThreads] " + str;
						break;
					case Role.Permission.CanEditPosts:
						query += " AND [CanEditPosts] " + str;
						break;
					case Role.Permission.CanEditHisThreads:
						query += " AND [CanEditHisThreads] " + str;
						break;
					case Role.Permission.CanEditHisPosts:
						query += " AND [CanEditHisPosts] " + str;
						break;
					case Role.Permission.CanDeleteGroups:
						query += " AND [CanDeleteGroups] " + str;
						break;
					case Role.Permission.CanDeleteThreads:
						query += " AND [CanDeleteThreads] " + str;
						break;
					case Role.Permission.CanDeletePosts:
						query += " AND [CanDeletePosts] " + str;
						break;
					case Role.Permission.CanDeleteHisThreads:
						query += " AND [CanDeleteHisThreads] " + str;
						break;
					case Role.Permission.CanDeleteHisPosts:
						query += " AND [CanDeleteHisPosts] " + str;
						break;
					case Role.Permission.CanManageMessageBoardSecurity:
						query += " AND [CanManageMessageBoardSecurity] " + str;
						break;
					case Role.Permission.CanManageGroupsSecurity:
						query += " AND [CanManageGroupsSecurity] " + str;
						break;
					case Role.Permission.CanManageCategoriesSecurity:
						query += " AND [CanManageCategoriesSecurity] " + str;
						break;
					case Role.Permission.CanManageForumsSecurity:
						query += " AND [CanManageForumsSecurity] " + str;
						break;
					case Role.Permission.CanManageThreadsSecurity:
						query += " AND [CanManageThreadsSecurity] " + str;
						break;
					case Role.Permission.CanManagePostsSecurity:
						query += " AND [CanManagePostsSecurity] " + str;
						break;
					default:
						break;

				}
			}

			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter(query, DbConnection);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		#endregion

		#endregion

		#region Methods
		public void Insert()
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter(@"
			INSERT INTO [" + Connection.tblRole + @"] 
			([UserId], [UserGroupId],
			[TheMessageBoard], [GroupId], [CategoryId], [ForumId], [ThreadId], [PostId],
			[CanViewGroups], [CanViewCategories], [CanViewForums], [CanViewThreads], [CanViewPosts],
			[CanAddGroups], 
			[CanAddCategories], 
			[CanAddForums], 
			[CanAddThreads], 
			[CanAddPosts], 
			[CanEditGroups], [CanEditCategories], [CanEditForums], [CanEditThreads], [CanEditPosts],
			[CanEditHisThreads], [CanEditHisPosts],
			[CanDeleteGroups], [CanDeleteCategories], [CanDeleteForums], [CanDeleteThreads], [CanDeletePosts],
			[CanDeleteHisThreads], [CanDeleteHisPosts],
			[CanManageMessageBoardSecurity], [CanManageGroupsSecurity], [CanManageCategoriesSecurity], [CanManageForumsSecurity], [CanManageThreadsSecurity], [CanManagePostsSecurity]
			)
			VALUES
			(
			@UserId, @UserGroupId,
			@TheMessageBoard, @GroupId, @CategoryId, @ForumId, @ThreadId, @PostId,
			@CanViewGroups, @CanViewCategories, @CanViewForums, @CanViewThreads, @CanViewPosts,
			@CanAddGroups, 
			@CanAddCategories, 
			@CanAddForums, 
			@CanAddThreads, 
			@CanAddPosts, 
			@CanEditGroups, @CanEditCategories, @CanEditForums, @CanEditThreads, @CanEditPosts,
			@CanEditHisThreads, @CanEditHisPosts,
			@CanDeleteGroups, @CanDeleteCategories, @CanDeleteForums, @CanDeleteThreads, @CanDeletePosts,
			@CanDeleteHisThreads, @CanDeleteHisPosts,
			@CanManageMessageBoardSecurity, @CanManageGroupsSecurity, @CanManageCategoriesSecurity, @CanManageForumsSecurity, @CanManageThreadsSecurity, @CanManagePostsSecurity
			);
			SELECT @@identity as i", DbConnection);
			
			if(User!=null)
				getData.SelectCommand.Parameters.Add("@UserId", User.Id);
			else
				getData.SelectCommand.Parameters.Add("@UserId", DBNull.Value);

			if(UserGroup!=null)
				getData.SelectCommand.Parameters.Add("@UserGroupId", UserGroup.Id);
			else
				getData.SelectCommand.Parameters.Add("@UserGroupId", DBNull.Value);

			getData.SelectCommand.Parameters.Add("@TheMessageBoard", TheMessageBoard);

			if(Group!=null)
				getData.SelectCommand.Parameters.Add("@GroupId", Group.Id);
			else
				getData.SelectCommand.Parameters.Add("@GroupId", DBNull.Value);

			if(Category!=null)
                getData.SelectCommand.Parameters.Add("@CategoryId", Category.Id);
			else
				getData.SelectCommand.Parameters.Add("@CategoryId", DBNull.Value);

			if(Forum!=null)
				getData.SelectCommand.Parameters.Add("@ForumId", Forum.Id);
			else
				getData.SelectCommand.Parameters.Add("@ForumId", DBNull.Value);

			if(Thread!=null)
				getData.SelectCommand.Parameters.Add("@ThreadId", Thread.Id);
			else
				getData.SelectCommand.Parameters.Add("@ThreadId", DBNull.Value);
			
			if(Post!=null)
				getData.SelectCommand.Parameters.Add("@PostId", Post.Id);
			else
				getData.SelectCommand.Parameters.Add("@PostId", DBNull.Value);
			
			getData.SelectCommand.Parameters.Add("@CanViewGroups", CanViewGroups);
			getData.SelectCommand.Parameters.Add("@CanViewCategories", CanViewCategories);
			getData.SelectCommand.Parameters.Add("@CanViewForums", CanViewForums);
			getData.SelectCommand.Parameters.Add("@CanViewThreads", CanViewThreads);
			getData.SelectCommand.Parameters.Add("@CanViewPosts", CanViewPosts);
			getData.SelectCommand.Parameters.Add("@CanAddGroups", CanAddGroups);
			getData.SelectCommand.Parameters.Add("@CanAddCategories", CanAddCategories);
			getData.SelectCommand.Parameters.Add("@CanAddForums", CanAddForums);
			getData.SelectCommand.Parameters.Add("@CanAddThreads", CanAddThreads);
			getData.SelectCommand.Parameters.Add("@CanAddPosts", CanAddPosts);
			getData.SelectCommand.Parameters.Add("@CanEditGroups", CanEditGroups);
			getData.SelectCommand.Parameters.Add("@CanEditCategories", CanEditCategories);
			getData.SelectCommand.Parameters.Add("@CanEditForums", CanEditForums);
			getData.SelectCommand.Parameters.Add("@CanEditThreads", CanEditThreads);
			getData.SelectCommand.Parameters.Add("@CanEditPosts", CanEditPosts);
			getData.SelectCommand.Parameters.Add("@CanEditHisThreads", CanEditHisThreads);
			getData.SelectCommand.Parameters.Add("@CanEditHisPosts", CanEditHisPosts);
			getData.SelectCommand.Parameters.Add("@CanDeleteGroups", CanDeleteGroups);
			getData.SelectCommand.Parameters.Add("@CanDeleteCategories", CanDeleteCategories);
			getData.SelectCommand.Parameters.Add("@CanDeleteForums", CanDeleteForums);
			getData.SelectCommand.Parameters.Add("@CanDeleteThreads", CanDeleteThreads);
			getData.SelectCommand.Parameters.Add("@CanDeletePosts", CanDeletePosts);
			getData.SelectCommand.Parameters.Add("@CanDeleteHisThreads", CanDeleteHisThreads);
			getData.SelectCommand.Parameters.Add("@CanDeleteHisPosts", CanDeleteHisPosts);
			getData.SelectCommand.Parameters.Add("@CanManageMessageBoardSecurity", CanManageMessageBoardSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageGroupsSecurity", CanManageGroupsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageCategoriesSecurity", CanManageCategoriesSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageForumsSecurity", CanManageForumsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageThreadsSecurity", CanManageThreadsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManagePostsSecurity", CanManagePostsSecurity);
			getData.Fill(ds);
			if(ds.Tables[0].Rows.Count>0)
			{
				Id = int.Parse(ds.Tables[0].Rows[0]["i"].ToString());
			}
		}

		public void Update()
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter(@"
			UPDATE [" + Connection.tblRole + @"] SET 

			[UserId] = @UserId,
			[UserGroupId] = @UserGroupId,
			[TheMessageBoard] = TheMessageBoard,
			[GroupId] = @GroupId,
			[CategoryId] = @CategoryId,
			[ForumId] = @ForumId,
			[ThreadId] = @ThreadId,
			[PostId] = @PostId,

			[CanViewGroups] = @CanViewGroups,
			[CanViewCategories] = @CanViewCategories,
			[CanViewForums] = @CanViewForums,
			[CanViewThreads] = @CanViewThreads,
			[CanViewPosts] = @CanViewPosts,

			[CanAddGroups] = @CanAddGroups,

			[CanAddCategories] = @CanAddCategories,

			[CanAddForums] = @CanAddForums,

			[CanAddThreads] = @CanAddThreads,

			[CanAddPosts] = @CanAddPosts,
			
			[CanEditGroups] = @CanEditGroups,
			[CanEditCategories] = @CanEditCategories,
			[CanEditForums] = @CanEditForums,
			[CanEditThreads] = @CanEditThreads,
			[CanEditPosts] = @CanEditPosts,

			[CanEditHisThreads] = @CanEditHisThreads,
			[CanEditHisPosts] = @CanEditHisPosts,

			[CanDeleteGroups] = @CanDeleteGroups,
			[CanDeleteCategories] = @CanDeleteCategories,
			[CanDeleteForums] = @CanDeleteForums,
			[CanDeleteThreads] = @CanDeleteThreads,
			[CanDeletePosts] = @CanDeletePosts,

			[CanDeleteHisThreads] = @CanDeleteHisThreads,
			[CanDeleteHisPosts] = @CanDeleteHisPosts,

			[CanManageMessageBoardSecurity] = @CanManageMessageBoardSecurity,
			[CanManageGroupsSecurity] = @CanManageGroupsSecurity,
			[CanManageCategoriesSecurity] = @CanManageCategoriesSecurity,
			[CanManageForumsSecurity] = @CanManageForumsSecurity,
			[CanManageThreadsSecurity] = @CanManageThreadsSecurity,
			[CanManagePostsSecurity] = @CanManagePostsSecurity
			WHERE [Id] = @Id", DbConnection);
			
			if(User!=null)
				getData.SelectCommand.Parameters.Add("@UserId", User.Id);
			else
				getData.SelectCommand.Parameters.Add("@UserId", DBNull.Value);

			if(UserGroup!=null)
				getData.SelectCommand.Parameters.Add("@UserGroupId", UserGroup.Id);
			else
				getData.SelectCommand.Parameters.Add("@UserGroupId", DBNull.Value);

			getData.SelectCommand.Parameters.Add("@TheMessageBoard", TheMessageBoard);

			if(Group!=null)
				getData.SelectCommand.Parameters.Add("@GroupId", Group.Id);
			else
				getData.SelectCommand.Parameters.Add("@GroupId", DBNull.Value);

			if(Category!=null)
				getData.SelectCommand.Parameters.Add("@CategoryId", Category.Id);
			else
				getData.SelectCommand.Parameters.Add("@CategoryId", DBNull.Value);

			if(Forum!=null)
				getData.SelectCommand.Parameters.Add("@ForumId", Forum.Id);
			else
				getData.SelectCommand.Parameters.Add("@ForumId", DBNull.Value);

			if(Thread!=null)
				getData.SelectCommand.Parameters.Add("@ThreadId", Thread.Id);
			else
				getData.SelectCommand.Parameters.Add("@ThreadId", DBNull.Value);
			
			if(Post!=null)
				getData.SelectCommand.Parameters.Add("@PostId", Post.Id);
			else
				getData.SelectCommand.Parameters.Add("@PostId", DBNull.Value);


			getData.SelectCommand.Parameters.Add("@CanViewGroups", CanViewGroups);
			getData.SelectCommand.Parameters.Add("@CanViewCategories", CanViewCategories);
			getData.SelectCommand.Parameters.Add("@CanViewForums", CanViewForums);
			getData.SelectCommand.Parameters.Add("@CanViewThreads", CanViewThreads);
			getData.SelectCommand.Parameters.Add("@CanViewPosts", CanViewPosts);
			getData.SelectCommand.Parameters.Add("@CanAddGroups", CanAddGroups);
			getData.SelectCommand.Parameters.Add("@CanAddCategories", CanAddCategories);
			getData.SelectCommand.Parameters.Add("@CanAddForums", CanAddForums);
			getData.SelectCommand.Parameters.Add("@CanAddThreads", CanAddThreads);
			getData.SelectCommand.Parameters.Add("@CanAddPosts", CanAddPosts);
			getData.SelectCommand.Parameters.Add("@CanEditGroups", CanEditGroups);
			getData.SelectCommand.Parameters.Add("@CanEditCategories", CanEditCategories);
			getData.SelectCommand.Parameters.Add("@CanEditForums", CanEditForums);
			getData.SelectCommand.Parameters.Add("@CanEditThreads", CanEditThreads);
			getData.SelectCommand.Parameters.Add("@CanEditPosts", CanEditPosts);
			getData.SelectCommand.Parameters.Add("@CanEditHisThreads", CanEditHisThreads);
			getData.SelectCommand.Parameters.Add("@CanEditHisPosts", CanEditHisPosts);
			getData.SelectCommand.Parameters.Add("@CanDeleteGroups", CanDeleteGroups);
			getData.SelectCommand.Parameters.Add("@CanDeleteCategories", CanDeleteCategories);
			getData.SelectCommand.Parameters.Add("@CanDeleteForums", CanDeleteForums);
			getData.SelectCommand.Parameters.Add("@CanDeleteThreads", CanDeleteThreads);
			getData.SelectCommand.Parameters.Add("@CanDeletePosts", CanDeletePosts);
			getData.SelectCommand.Parameters.Add("@CanDeleteHisThreads", CanDeleteHisThreads);
			getData.SelectCommand.Parameters.Add("@CanDeleteHisPosts", CanDeleteHisPosts);
			getData.SelectCommand.Parameters.Add("@CanManageMessageBoardSecurity", CanManageMessageBoardSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageGroupsSecurity", CanManageGroupsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageCategoriesSecurity", CanManageCategoriesSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageForumsSecurity", CanManageForumsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManageThreadsSecurity", CanManageThreadsSecurity);
			getData.SelectCommand.Parameters.Add("@CanManagePostsSecurity", CanManagePostsSecurity);
			
			getData.SelectCommand.Parameters.Add("@Id", Id);
			getData.Fill(ds);
		}

		public void Delete()
		{
			DataSet ds = new DataSet();
			SqlDataAdapter getData = new SqlDataAdapter(@"
			DELETE FROM [" + Connection.tblRole + @"] WHERE [Id] = @Id", DbConnection);
			getData.SelectCommand.Parameters.Add("@Id", Id);
			getData.Fill(ds);
		}

		#endregion

		#region Properties

		public int Id
		{
			get
			{
				return _Id;
			}
			set
			{
				_Id = value;
			}
		}

		public User User
		{
			get
			{
				return _User;
			}
			set
			{
				_User = value;
			}
		}

		public UserGroup UserGroup
		{
			get
			{
				return _UserGroup;
			}
			set
			{ 
				_UserGroup = value;
			}
		}

		public Boolean TheMessageBoard
		{
			get
			{
				return _TheMessageBoard;
			}
			set
			{ 
				_TheMessageBoard = value;
			}
		}

		public Group Group
		{
			get
			{
				return _Group;
			}
			set
			{
				_Group = value;
			}
		}

		public Category Category
		{
			get
			{
				return _Category;
			}
			set
			{
				_Category = value;
			}
		}

		public Forum Forum
		{
			get
			{
				return _Forum;
			}
			set
			{
				_Forum = value;
			}
		}

		public Thread Thread
		{
			get
			{
				return _Thread;
			}
			set
			{
				_Thread = value;
			}
		}

		public Post Post
		{
			get
			{
				return _Post;
			}
			set
			{
				_Post = value;
			}
		}

		public Allow CanViewGroups
		{
			get
			{
				return _CanViewGroups;
			}
			set
			{
				_CanViewGroups = value;
			}
		}

		public Allow CanViewCategories
		{
			get
			{
				return _CanViewCategories;
			}
			set
			{
				_CanViewCategories = value;
			}
		}

		public Allow CanViewForums
		{
			get
			{
				return _CanViewForums;
			}
			set
			{
				_CanViewForums = value;
			}
		}

		public Allow CanViewThreads
		{
			get
			{
				return _CanViewThreads;
			}
			set
			{
				_CanViewThreads = value;
			}
		}

		public Allow CanViewPosts
		{
			get
			{
				return _CanViewPosts;
			}
			set
			{
				_CanViewPosts = value;
			}
		}

		public Allow CanAddGroups
		{
			get
			{
				return _CanAddGroups;
			}
			set
			{
				_CanAddGroups = value;
			}
		}

		public Allow CanAddCategories
		{
			get
			{
				return _CanAddCategories;
			}
			set
			{
				_CanAddCategories = value;
			}
		}

		public Allow CanAddForums
		{
			get
			{
				return _CanAddForums;
			}
			set
			{
				_CanAddForums = value;
			}
		}

		public Allow CanAddThreads
		{
			get
			{
				return _CanAddThreads;
			}
			set
			{
				_CanAddThreads = value;
			}
		}

		public Allow CanAddPosts
		{
			get
			{
				return _CanAddPosts;
			}
			set
			{
				_CanAddPosts = value;
			}
		}

		public Allow CanEditGroups
		{
			get
			{
				return _CanEditGroups;
			}
			set
			{
				_CanEditGroups = value;
			}
		}

		public Allow CanEditCategories
		{
			get
			{
				return _CanEditCategories;
			}
			set
			{
				_CanEditCategories = value;
			}
		}

		public Allow CanEditForums
		{
			get
			{
				return _CanEditForums;
			}
			set
			{
				_CanEditForums = value;
			}
		}

		public Allow CanEditThreads
		{
			get
			{
				return _CanEditThreads;
			}
			set
			{
				_CanEditThreads = value;
			}
		}

		public Allow CanEditPosts
		{
			get
			{
				return _CanEditPosts;
			}
			set
			{
				_CanEditPosts = value;
			}
		}

		public Allow CanEditHisThreads
		{
			get
			{
				return _CanEditHisThreads;
			
			}
			set
			{
				_CanEditHisThreads = value;
			}
		}

		public Allow CanEditHisPosts
		{
			get
			{
				return _CanEditHisPosts;
			}
			set
			{
				_CanEditHisPosts = value;
			}
		}

		public Allow CanDeleteGroups
		{
			get
			{
				return _CanDeleteGroups;
			}
			set
			{
				_CanDeleteGroups = value;
			}
		}

		public Allow CanDeleteCategories
		{
			get
			{
				return _CanDeleteCategories;
			}
			set
			{
				_CanDeleteCategories = value;
			}
		}

		public Allow CanDeleteForums
		{
			get
			{
				return _CanDeleteForums;
			}
			set
			{ 
				_CanDeleteForums = value;
			}
		}

		public Allow CanDeleteThreads
		{
			get
			{
				return _CanDeleteThreads;
			}
			set
			{
				_CanDeleteThreads = value;
			}
		}

		public Allow CanDeletePosts
		{
			get
			{
				return _CanDeletePosts;
			}
			set
			{
				_CanDeletePosts = value;
			}
		}

		public Allow CanDeleteHisThreads
		{
			get
			{
				return _CanDeleteHisThreads;
			}
			set
			{
				_CanDeleteHisThreads = value;
			}
		}

		public Allow CanDeleteHisPosts
		{
			get
			{
				return _CanDeleteHisPosts;
			}
			set
			{
				_CanDeleteHisPosts = value;
			}
		}

		public Allow CanManageMessageBoardSecurity
		{
			get
			{
				return _CanManageMessageBoardSecurity;
			}
			set
			{
				_CanManageMessageBoardSecurity = value;
			}
		}

		public Allow CanManageGroupsSecurity
		{
			get
			{
				return _CanManageGroupsSecurity;
			}
			set
			{
				_CanManageGroupsSecurity = value;
			}
		}

		public Allow CanManageCategoriesSecurity
		{
			get
			{
				return _CanManageCategoriesSecurity;
			}
			set
			{
				_CanManageCategoriesSecurity = value;
			}
		}

		public Allow CanManageForumsSecurity
		{
			get
			{
				return _CanManageForumsSecurity;
			}
			set
			{
				_CanManageForumsSecurity = value;
			}
		}

		public Allow CanManageThreadsSecurity
		{
			get
			{
				return _CanManageThreadsSecurity;
			}
			set
			{
				_CanManageThreadsSecurity = value;
			}
		}

		public Allow CanManagePostsSecurity
		{
			get
			{
				return _CanManagePostsSecurity;
			}
			set
			{
				_CanManagePostsSecurity = value;
			}
		}

		#endregion

		#region Enum
		public enum Permission
		{
			CanViewGroups,
			CanViewCategories,
			CanViewForums,
			CanViewThreads,
			CanViewPosts,
			CanAddGroups,
			CanAddCategories,
			CanAddForums,
			CanAddThreads,
			CanAddPosts,
			CanEditGroups,
			CanEditCategories,
			CanEditForums,
			CanEditThreads,
			CanEditPosts,
			CanEditHisThreads,
			CanEditHisPosts,
			CanDeleteGroups,
			CanDeleteCategories,
			CanDeleteForums,
			CanDeleteThreads,
			CanDeletePosts,
			CanDeleteHisThreads,
			CanDeleteHisPosts,
			CanManageMessageBoardSecurity,
			CanManageGroupsSecurity,
			CanManageCategoriesSecurity,
			CanManageForumsSecurity,
			CanManageThreadsSecurity,
			CanManagePostsSecurity,
		}

		public enum Allow
		{
			Yes =1,
			No = 2,
			AsParent = 0
		}
		#endregion
	}
}
